Set up the Core Components of the Code

# Each team member would need to set their directory path to variable "project_dir"
# we will make sure everything else is relative to "project_dir"
project_dir <- "/home/admin-12/Documents/IMARTICUS/Data-Riders"
setwd(project_dir)

# Setup Packages
load_packages <- function () {
  # Imports
  packages <- c("VIM", "dplyr", "plotly", "psych", "corrplot", "cluster", "factoextra")
  installed_packages <- packages %in% rownames(installed.packages())
  if (any(installed_packages == FALSE)) {
    install.packages(packages[!installed_packages])
  }
  # Packages loading with suppressed messages
  suppressMessages(invisible(lapply(packages, library, character.only = TRUE)))
}
load_packages()

# Get the Raw Data from the file
read_file <- function () {
  data <- read.csv("data/cereals_data.csv")
  return (data)
}

# Handle missing values
handle_missing_values <- function (input) {
  output <- input
  # any handling of missing values
  output <- na.omit(output)
  # TODO KNN
  return (output)
}

# Clearn the data to make it good for processing
# eg. delete unwanted rows, change data types etc
data_processing <- function (input) {
  output <- input
  output <- handle_missing_values(output)

  # Set company names
  output$mfr_names <- as.character(output$mfr)
  output$mfr_names[output$mfr_names=="A"] <- "American Home Food Products"
  output$mfr_names[output$mfr_names=="G"] <- "General Mills"
  output$mfr_names[output$mfr_names=="K"] <- "Kelloggs"
  output$mfr_names[output$mfr_names=="N"] <- "Nabisco"
  output$mfr_names[output$mfr_names=="P"] <- "Post"
  output$mfr_names[output$mfr_names=="Q"] <- "Quaker Oats"
  output$mfr_names[output$mfr_names=="R"] <- "Ralston Purina"
  output$mfr_names_factor = as.factor(output$mfr_names)

  # Calorie Categories
  output <- within(output, {
    calories_category <- NA
    calories_category[calories>=50&calories<80] <- "L"
    calories_category[calories>=80&calories<110] <- "M"
    calories_category[calories>=110] <- "H"
  })

  # some data processing steps that would be required
  return (output)
}

# Get the Data Frame for the data
get_data <- function () {
  raw <- read_file()
  data <- data_processing(raw)
  return (data)
}

data <- get_data()

Evaluation of the Data Set

Density Chart for Calorie

plot(density(data$calories), ylab = "Probabilty Density", xlab = "Calories")

Top 10 Cerials that have high rating

d <- data %>% arrange(rating) %>% head(10) %>% select(name, rating)
ggplot(data=d, aes(x=name, y=rating)) + geom_bar(stat = "identity")

Calories and Cups

plot(data$calories, data$weight)

Correlation View of Variables

data_grp_mfr <- data %>%
  group_by(mfr_names_factor)
cor_result <- cor((data_grp_mfr %>% select_if(is.numeric))[-1])
corrplot(cor_result)

heatmap(cor_result)

Distribution of Cups Per Serving

data %>% ggplot(aes(x = weight, fill = mfr_names)) + geom_histogram() + scale_fill_brewer(palette = "Set5") +
    scale_x_continuous(name = "Weight (in ounces)", expand = c(0,0)) +
    labs(fill = "Manufacturer", title = "Distribution of Weight per Serving", subtitle = "different weights for servings") +
    theme_classic()
Warning in pal_name(palette, type): Unknown palette Set5
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Distribution of cups per Serving

data %>% ggplot(aes(x = cups, fill = mfr)) + geom_histogram() + scale_fill_brewer(palette = "Spectral") + scale_x_continuous(name = "no of cups", expand = c(0,0)) + labs(fill = "Manufacturer", title = "Distribution of cups per Serving", subtitle = "different cups for servings") + theme_classic()
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Distribution of rating vs cal

data %>% ggplot(aes(x = rating, fill = calories_category)) + geom_histogram() + scale_fill_brewer(palette = "Set1") + scale_x_continuous(name = "Ratings", expand = c(0,0)) + labs(fill = " Cal ",y ='count', title = "Distribution of Ratings vs cal", subtitle = "Low rating for Hogh calories") + theme_classic()
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Mfr wise calorie distribution

count_cal <- data %>% group_by(mfr_names) %>% count(calories_category)
ggplot(count_cal,aes(x=reorder(calories_category,n),y=n,fill=mfr_names))+geom_bar(stat='identity')+ labs(x='cal',y='count',title='Mfr wise calorie distribution')

Company wise Rating Consistency

data_grp_mfr %>% plot_ly(y= ~rating, x= ~mfr_names_factor, type = "box", color= ~mfr_names_factor) %>%
  layout(title="Product Consistency", xaxis=list(title="Manufactures"), yaxis=list(title="Rating"))

Company wise Calorie Constency

data_grp_mfr %>% plot_ly(y= ~calories, x= ~mfr_names_factor, type = "box", color= ~mfr_names_factor) %>%
  layout(title="Product Consistency (by Calories)", xaxis=list(title="Manufactures"), yaxis=list(title="Calories"))

Word Cloud

print("Word Cloud")
[1] "Word Cloud"

Cluster Analysis

cluster_data <- data %>% select(calories, rating, protein, fat)
km.res <- kmeans(cluster_data, 5, nstart = 25)
fviz_cluster(km.res, data=cluster_data, palette = "jco", ggtheme = theme_minimal())

Good and Bad parameters for rating

cor_result_rating <- cor_result["rating",]
cor_result_rating_names <- names(cor_result_rating)
names(cor_result_rating) <- NULL
cor_result_df <- data.frame(cor_result_rating_names, cor_result_rating) %>% arrange(cor_result_rating)
names(cor_result_df) <- c("Parameters", "Corellation")
ggplot(cor_result_df, aes(x=Parameters, y=Corellation)) + geom_bar(stat = "identity")

prediction with liner model

model <- lm(rating~sugars+calories+protein+fat+sodium+fiber+carbo+potass+vitamins+shelf+weight+cups, data=data)
changed_data <- data
changed_data[changed_data$name=="100%_Natural_Bran",]$carbo
[1] 8
changed_data[changed_data$name=="100%_Natural_Bran",]$carbo <- 15
data.frame(data, predicted_rating=predict(model, changed_data))[changed_data$name=="100%_Natural_Bran",]
LS0tCnRpdGxlOiAiRGF0YSBSaWRlcnMgTm90ZWJvb2siCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCi0tLQoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KLm1haW4tY29udGFpbmVyIHsKICBtYXgtd2lkdGg6IDEzMDBweDsKICBtYXJnaW4tbGVmdDogYXV0bzsKICBtYXJnaW4tcmlnaHQ6IGF1dG87Cn0KCnAgewogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtc2l6ZTogMTUwJTsKfQo8L3N0eWxlPgoKU2V0IHVwIHRoZSBDb3JlIENvbXBvbmVudHMgb2YgdGhlIENvZGUKYGBge3J9CiMgRWFjaCB0ZWFtIG1lbWJlciB3b3VsZCBuZWVkIHRvIHNldCB0aGVpciBkaXJlY3RvcnkgcGF0aCB0byB2YXJpYWJsZSAicHJvamVjdF9kaXIiCiMgd2Ugd2lsbCBtYWtlIHN1cmUgZXZlcnl0aGluZyBlbHNlIGlzIHJlbGF0aXZlIHRvICJwcm9qZWN0X2RpciIKcHJvamVjdF9kaXIgPC0gIi9ob21lL2FkbWluLTEyL0RvY3VtZW50cy9JTUFSVElDVVMvRGF0YS1SaWRlcnMiCnNldHdkKHByb2plY3RfZGlyKQoKIyBTZXR1cCBQYWNrYWdlcwpsb2FkX3BhY2thZ2VzIDwtIGZ1bmN0aW9uICgpIHsKICAjIEltcG9ydHMKICBwYWNrYWdlcyA8LSBjKCJWSU0iLCAiZHBseXIiLCAicGxvdGx5IiwgInBzeWNoIiwgImNvcnJwbG90IiwgImNsdXN0ZXIiLCAiZmFjdG9leHRyYSIpCiAgaW5zdGFsbGVkX3BhY2thZ2VzIDwtIHBhY2thZ2VzICVpbiUgcm93bmFtZXMoaW5zdGFsbGVkLnBhY2thZ2VzKCkpCiAgaWYgKGFueShpbnN0YWxsZWRfcGFja2FnZXMgPT0gRkFMU0UpKSB7CiAgICBpbnN0YWxsLnBhY2thZ2VzKHBhY2thZ2VzWyFpbnN0YWxsZWRfcGFja2FnZXNdKQogIH0KICAjIFBhY2thZ2VzIGxvYWRpbmcgd2l0aCBzdXBwcmVzc2VkIG1lc3NhZ2VzCiAgc3VwcHJlc3NNZXNzYWdlcyhpbnZpc2libGUobGFwcGx5KHBhY2thZ2VzLCBsaWJyYXJ5LCBjaGFyYWN0ZXIub25seSA9IFRSVUUpKSkKfQpsb2FkX3BhY2thZ2VzKCkKCiMgR2V0IHRoZSBSYXcgRGF0YSBmcm9tIHRoZSBmaWxlCnJlYWRfZmlsZSA8LSBmdW5jdGlvbiAoKSB7CiAgZGF0YSA8LSByZWFkLmNzdigiZGF0YS9jZXJlYWxzX2RhdGEuY3N2IikKICByZXR1cm4gKGRhdGEpCn0KCiMgSGFuZGxlIG1pc3NpbmcgdmFsdWVzCmhhbmRsZV9taXNzaW5nX3ZhbHVlcyA8LSBmdW5jdGlvbiAoaW5wdXQpIHsKICBvdXRwdXQgPC0gaW5wdXQKICAjIGFueSBoYW5kbGluZyBvZiBtaXNzaW5nIHZhbHVlcwogIG91dHB1dCA8LSBuYS5vbWl0KG91dHB1dCkKICAjIFRPRE8gS05OCiAgcmV0dXJuIChvdXRwdXQpCn0KCiMgQ2xlYXJuIHRoZSBkYXRhIHRvIG1ha2UgaXQgZ29vZCBmb3IgcHJvY2Vzc2luZwojIGVnLiBkZWxldGUgdW53YW50ZWQgcm93cywgY2hhbmdlIGRhdGEgdHlwZXMgZXRjCmRhdGFfcHJvY2Vzc2luZyA8LSBmdW5jdGlvbiAoaW5wdXQpIHsKICBvdXRwdXQgPC0gaW5wdXQKICBvdXRwdXQgPC0gaGFuZGxlX21pc3NpbmdfdmFsdWVzKG91dHB1dCkKCiAgIyBTZXQgY29tcGFueSBuYW1lcwogIG91dHB1dCRtZnJfbmFtZXMgPC0gYXMuY2hhcmFjdGVyKG91dHB1dCRtZnIpCiAgb3V0cHV0JG1mcl9uYW1lc1tvdXRwdXQkbWZyX25hbWVzPT0iQSJdIDwtICJBbWVyaWNhbiBIb21lIEZvb2QgUHJvZHVjdHMiCiAgb3V0cHV0JG1mcl9uYW1lc1tvdXRwdXQkbWZyX25hbWVzPT0iRyJdIDwtICJHZW5lcmFsIE1pbGxzIgogIG91dHB1dCRtZnJfbmFtZXNbb3V0cHV0JG1mcl9uYW1lcz09IksiXSA8LSAiS2VsbG9nZ3MiCiAgb3V0cHV0JG1mcl9uYW1lc1tvdXRwdXQkbWZyX25hbWVzPT0iTiJdIDwtICJOYWJpc2NvIgogIG91dHB1dCRtZnJfbmFtZXNbb3V0cHV0JG1mcl9uYW1lcz09IlAiXSA8LSAiUG9zdCIKICBvdXRwdXQkbWZyX25hbWVzW291dHB1dCRtZnJfbmFtZXM9PSJRIl0gPC0gIlF1YWtlciBPYXRzIgogIG91dHB1dCRtZnJfbmFtZXNbb3V0cHV0JG1mcl9uYW1lcz09IlIiXSA8LSAiUmFsc3RvbiBQdXJpbmEiCiAgb3V0cHV0JG1mcl9uYW1lc19mYWN0b3IgPSBhcy5mYWN0b3Iob3V0cHV0JG1mcl9uYW1lcykKCiAgIyBDYWxvcmllIENhdGVnb3JpZXMKICBvdXRwdXQgPC0gd2l0aGluKG91dHB1dCwgewogICAgY2Fsb3JpZXNfY2F0ZWdvcnkgPC0gTkEKICAgIGNhbG9yaWVzX2NhdGVnb3J5W2NhbG9yaWVzPj01MCZjYWxvcmllczw4MF0gPC0gIkwiCiAgICBjYWxvcmllc19jYXRlZ29yeVtjYWxvcmllcz49ODAmY2Fsb3JpZXM8MTEwXSA8LSAiTSIKICAgIGNhbG9yaWVzX2NhdGVnb3J5W2NhbG9yaWVzPj0xMTBdIDwtICJIIgogIH0pCgogICMgc29tZSBkYXRhIHByb2Nlc3Npbmcgc3RlcHMgdGhhdCB3b3VsZCBiZSByZXF1aXJlZAogIHJldHVybiAob3V0cHV0KQp9CgojIEdldCB0aGUgRGF0YSBGcmFtZSBmb3IgdGhlIGRhdGEKZ2V0X2RhdGEgPC0gZnVuY3Rpb24gKCkgewogIHJhdyA8LSByZWFkX2ZpbGUoKQogIGRhdGEgPC0gZGF0YV9wcm9jZXNzaW5nKHJhdykKICByZXR1cm4gKGRhdGEpCn0KCmRhdGEgPC0gZ2V0X2RhdGEoKQpgYGAKCkV2YWx1YXRpb24gb2YgdGhlIERhdGEgU2V0CmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRlc2NyaWJlKGRhdGEpCmBgYAoKRGVuc2l0eSBDaGFydCBmb3IgQ2Fsb3JpZQpgYGB7cn0KcGxvdChkZW5zaXR5KGRhdGEkY2Fsb3JpZXMpLCB5bGFiID0gIlByb2JhYmlsdHkgRGVuc2l0eSIsIHhsYWIgPSAiQ2Fsb3JpZXMiKQpgYGAKClRvcCAxMCBDZXJpYWxzIHRoYXQgaGF2ZSBoaWdoIHJhdGluZwpgYGB7cn0KZCA8LSBkYXRhICU+JSBhcnJhbmdlKHJhdGluZykgJT4lIGhlYWQoMTApICU+JSBzZWxlY3QobmFtZSwgcmF0aW5nKQpnZ3Bsb3QoZGF0YT1kLCBhZXMoeD1uYW1lLCB5PXJhdGluZykpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpCmBgYAoKQ2Fsb3JpZXMgYW5kIEN1cHMKYGBge3J9CnBsb3QoZGF0YSRjYWxvcmllcywgZGF0YSR3ZWlnaHQpCmBgYAoKQ29ycmVsYXRpb24gVmlldyBvZiBWYXJpYWJsZXMKYGBge3J9CmRhdGFfZ3JwX21mciA8LSBkYXRhICU+JQogIGdyb3VwX2J5KG1mcl9uYW1lc19mYWN0b3IpCmNvcl9yZXN1bHQgPC0gY29yKChkYXRhX2dycF9tZnIgJT4lIHNlbGVjdF9pZihpcy5udW1lcmljKSlbLTFdKQpjb3JycGxvdChjb3JfcmVzdWx0KQpoZWF0bWFwKGNvcl9yZXN1bHQpCmBgYAoKRGlzdHJpYnV0aW9uIG9mIEN1cHMgUGVyIFNlcnZpbmcKYGBge3J9CmRhdGEgJT4lIGdncGxvdChhZXMoeCA9IHdlaWdodCwgZmlsbCA9IG1mcl9uYW1lcykpICsgZ2VvbV9oaXN0b2dyYW0oKSArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0NSIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIldlaWdodCAoaW4gb3VuY2VzKSIsIGV4cGFuZCA9IGMoMCwwKSkgKwogICAgbGFicyhmaWxsID0gIk1hbnVmYWN0dXJlciIsIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBXZWlnaHQgcGVyIFNlcnZpbmciLCBzdWJ0aXRsZSA9ICJkaWZmZXJlbnQgd2VpZ2h0cyBmb3Igc2VydmluZ3MiKSArCiAgICB0aGVtZV9jbGFzc2ljKCkKYGBgCgpEaXN0cmlidXRpb24gb2YgY3VwcyBwZXIgU2VydmluZwpgYGB7cn0KZGF0YSAlPiUgZ2dwbG90KGFlcyh4ID0gY3VwcywgZmlsbCA9IG1mcikpICsgZ2VvbV9oaXN0b2dyYW0oKSArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIm5vIG9mIGN1cHMiLCBleHBhbmQgPSBjKDAsMCkpICsgbGFicyhmaWxsID0gIk1hbnVmYWN0dXJlciIsIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBjdXBzIHBlciBTZXJ2aW5nIiwgc3VidGl0bGUgPSAiZGlmZmVyZW50IGN1cHMgZm9yIHNlcnZpbmdzIikgKyB0aGVtZV9jbGFzc2ljKCkKYGBgCgpEaXN0cmlidXRpb24gb2YgcmF0aW5nIHZzIGNhbApgYGB7cn0KZGF0YSAlPiUgZ2dwbG90KGFlcyh4ID0gcmF0aW5nLCBmaWxsID0gY2Fsb3JpZXNfY2F0ZWdvcnkpKSArIGdlb21faGlzdG9ncmFtKCkgKyBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlJhdGluZ3MiLCBleHBhbmQgPSBjKDAsMCkpICsgbGFicyhmaWxsID0gIiBDYWwgIix5ID0nY291bnQnLCB0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgUmF0aW5ncyB2cyBjYWwiLCBzdWJ0aXRsZSA9ICJMb3cgcmF0aW5nIGZvciBIb2doIGNhbG9yaWVzIikgKyB0aGVtZV9jbGFzc2ljKCkKYGBgCgpNZnIgd2lzZSBjYWxvcmllIGRpc3RyaWJ1dGlvbgpgYGB7cn0KY291bnRfY2FsIDwtIGRhdGEgJT4lIGdyb3VwX2J5KG1mcl9uYW1lcykgJT4lIGNvdW50KGNhbG9yaWVzX2NhdGVnb3J5KQpnZ3Bsb3QoY291bnRfY2FsLGFlcyh4PXJlb3JkZXIoY2Fsb3JpZXNfY2F0ZWdvcnksbikseT1uLGZpbGw9bWZyX25hbWVzKSkrZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknKSsgbGFicyh4PSdjYWwnLHk9J2NvdW50Jyx0aXRsZT0nTWZyIHdpc2UgY2Fsb3JpZSBkaXN0cmlidXRpb24nKQpgYGAKCkNvbXBhbnkgd2lzZSBSYXRpbmcgQ29uc2lzdGVuY3kKYGBge3Igb3V0LndpZHRoPSIxMDAlIn0KZGF0YV9ncnBfbWZyICU+JSBwbG90X2x5KHk9IH5yYXRpbmcsIHg9IH5tZnJfbmFtZXNfZmFjdG9yLCB0eXBlID0gImJveCIsIGNvbG9yPSB+bWZyX25hbWVzX2ZhY3RvcikgJT4lCiAgbGF5b3V0KHRpdGxlPSJQcm9kdWN0IENvbnNpc3RlbmN5IiwgeGF4aXM9bGlzdCh0aXRsZT0iTWFudWZhY3R1cmVzIiksIHlheGlzPWxpc3QodGl0bGU9IlJhdGluZyIpKQoKYGBgCgpDb21wYW55IHdpc2UgQ2Fsb3JpZSBDb25zdGVuY3kKYGBge3J9CmRhdGFfZ3JwX21mciAlPiUgcGxvdF9seSh5PSB+Y2Fsb3JpZXMsIHg9IH5tZnJfbmFtZXNfZmFjdG9yLCB0eXBlID0gImJveCIsIGNvbG9yPSB+bWZyX25hbWVzX2ZhY3RvcikgJT4lCiAgbGF5b3V0KHRpdGxlPSJQcm9kdWN0IENvbnNpc3RlbmN5IChieSBDYWxvcmllcykiLCB4YXhpcz1saXN0KHRpdGxlPSJNYW51ZmFjdHVyZXMiKSwgeWF4aXM9bGlzdCh0aXRsZT0iQ2Fsb3JpZXMiKSkKYGBgCgpXb3JkIENsb3VkCmBgYHtyfQpwcmludCgiV29yZCBDbG91ZCIpCmBgYAoKQ2x1c3RlciBBbmFseXNpcwpgYGB7cn0KY2x1c3Rlcl9kYXRhIDwtIGRhdGEgJT4lIHNlbGVjdChjYWxvcmllcywgcmF0aW5nLCBwcm90ZWluLCBmYXQpCmttLnJlcyA8LSBrbWVhbnMoY2x1c3Rlcl9kYXRhLCA1LCBuc3RhcnQgPSAyNSkKZnZpel9jbHVzdGVyKGttLnJlcywgZGF0YT1jbHVzdGVyX2RhdGEsIHBhbGV0dGUgPSAiamNvIiwgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKYGBgCgpHb29kIGFuZCBCYWQgcGFyYW1ldGVycyBmb3IgcmF0aW5nCmBgYHtyfQpjb3JfcmVzdWx0X3JhdGluZyA8LSBjb3JfcmVzdWx0WyJyYXRpbmciLF0KY29yX3Jlc3VsdF9yYXRpbmdfbmFtZXMgPC0gbmFtZXMoY29yX3Jlc3VsdF9yYXRpbmcpCm5hbWVzKGNvcl9yZXN1bHRfcmF0aW5nKSA8LSBOVUxMCmNvcl9yZXN1bHRfZGYgPC0gZGF0YS5mcmFtZShjb3JfcmVzdWx0X3JhdGluZ19uYW1lcywgY29yX3Jlc3VsdF9yYXRpbmcpICU+JSBhcnJhbmdlKGNvcl9yZXN1bHRfcmF0aW5nKQpuYW1lcyhjb3JfcmVzdWx0X2RmKSA8LSBjKCJQYXJhbWV0ZXJzIiwgIkNvcmVsbGF0aW9uIikKZ2dwbG90KGNvcl9yZXN1bHRfZGYsIGFlcyh4PVBhcmFtZXRlcnMsIHk9Q29yZWxsYXRpb24pKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKQpgYGAKCnByZWRpY3Rpb24gd2l0aCBsaW5lciBtb2RlbApgYGB7cn0KbW9kZWwgPC0gbG0ocmF0aW5nfnN1Z2FycytjYWxvcmllcytwcm90ZWluK2ZhdCtzb2RpdW0rZmliZXIrY2FyYm8rcG90YXNzK3ZpdGFtaW5zK3NoZWxmK3dlaWdodCtjdXBzLCBkYXRhPWRhdGEpCmNoYW5nZWRfZGF0YSA8LSBkYXRhCmNoYW5nZWRfZGF0YVtjaGFuZ2VkX2RhdGEkbmFtZT09IjEwMCVfTmF0dXJhbF9CcmFuIixdJGNhcmJvCmNoYW5nZWRfZGF0YVtjaGFuZ2VkX2RhdGEkbmFtZT09IjEwMCVfTmF0dXJhbF9CcmFuIixdJGNhcmJvIDwtIDE1CmRhdGEuZnJhbWUoZGF0YSwgcHJlZGljdGVkX3JhdGluZz1wcmVkaWN0KG1vZGVsLCBjaGFuZ2VkX2RhdGEpKVtjaGFuZ2VkX2RhdGEkbmFtZT09IjEwMCVfTmF0dXJhbF9CcmFuIixdCmBgYAo=